﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace AudiPyme.DAL
{
    public class InstanciaTiposActivosAmenazasCriteriosRiesgoFactory
    {
        //Método que elimina una lista de relaciones Tipo Activo - Amenaza - Criterios de riesgo actuales seleccionadas por una empresa
        public static void EliminarInstanciaTipActAmenCrit(int IdTipoActivo, int IdAmenaza, int IdCriterioRiesgo, int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Recogemos las instancias de la BD de la empresa que se correspondan con los de la lista
            InstanciaTiposActivosAmenazasCriteriosRiesgo InstanciaEliminar
                        = (from InstTipAmenCrit in agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer
                           where InstTipAmenCrit.IdTipoActivo == IdTipoActivo &&
                                 InstTipAmenCrit.IdAmenaza == IdAmenaza &&
                                 InstTipAmenCrit.IdCriterioRiesgo == IdCriterioRiesgo &&
                                 InstTipAmenCrit.Actual == true
                           select InstTipAmenCrit).First();
            InstanciaEliminar.Actual = false;
            agenteBD.SaveChanges();
            System.Threading.Thread.Sleep(100);
        }

        //Método que elimina (borrado lógico, las pone a false) todas las ocurrencias de relaciones con IdTipoActivo, IdAmenaza de una Empresa, sin tener en cuenta Criterios de Riesgo
        public static void EliminarInstanciaTipActAmenCrit(int IdEmpresa, int IdTipoActivo, int IdAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<InstanciaTiposActivosAmenazasCriteriosRiesgo> InstanciaEliminar = from InstTipAmenCrit in agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer
                                                                                         where InstTipAmenCrit.IdTipoActivo == IdTipoActivo &&
                                                                                               InstTipAmenCrit.IdAmenaza == IdAmenaza &&
                                                                                               InstTipAmenCrit.IdEmpresa == IdEmpresa
                                                                                         select InstTipAmenCrit;

            //Eliminamos todas las ocurrencias de relaciones con IdTipoActivo, IdAmenaza, sin tener en cuenta Criterios de Riesgo
            foreach (InstanciaTiposActivosAmenazasCriteriosRiesgo InstElim in InstanciaEliminar)
            {
                InstElim.Actual = false;
            }
            agenteBD.SaveChanges();
        }

        //Método que inserta un elemento instancia tipo activo - amenaza - criterio de riesgo
        public static void InsertarInstanciaTipActAmenCrit(InstanciaTiposActivosAmenazasCriteriosRiesgo instancia)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            agenteBD.AddToInstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer(instancia);
            agenteBD.SaveChanges();
        }

        //Método que inserta una nueva instancia de una relación Tipo Activo - Amenaza - Criterio 
        //(Comprueba si estaba insertada anteriormente pero con Actual=false y si es así sólo cambia ese atributo)
        public static void InsertarInstanciaTipActAmenCrit(InstanciaTiposActivosAmenazasCriteriosRiesgo instancia, int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            if (EstaHistoricoInstanciaTipActAmenCrit(instancia, IdEmpresa))
            {
                InstanciaTiposActivosAmenazasCriteriosRiesgo Instancia = (from i in agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer
                                                                          where i.IdTipoActivo == instancia.IdTipoActivo &&
                                                                          i.IdAmenaza == instancia.IdAmenaza &&
                                                                          i.IdCriterioRiesgo == instancia.IdCriterioRiesgo
                                                                          && i.IdEmpresa == IdEmpresa
                                                                          select i).First();
                Instancia.Actual = true;
            }
            else
            {
                agenteBD.AddToInstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer(instancia);
            }
            agenteBD.SaveChanges();
        }

        //Método que inserta una nueva instancia de una relación Tipo Activo - Amenaza - Criterio de Riesgo 
        public static void InsertarInstanciaTipActAmenCrit(int IdEmpresa, int IdTipoActivo, int IdAmenaza, int IdCriterioRiesgo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Rellenamos la instancia con los valores correspondientes
            InstanciaTiposActivosAmenazasCriteriosRiesgo nuevaInstancia =
                new InstanciaTiposActivosAmenazasCriteriosRiesgo();
            nuevaInstancia.IdEmpresa = IdEmpresa;
            nuevaInstancia.IdTipoActivo = IdTipoActivo;
            nuevaInstancia.IdAmenaza = IdAmenaza;
            nuevaInstancia.IdCriterioRiesgo = IdCriterioRiesgo;
            //Ponemos Actual=true ya que es una relación que actualmente está seleccionada por la empresa
            nuevaInstancia.Actual = true;
            InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.InsertarInstanciaTipActAmenCrit(nuevaInstancia, IdEmpresa);
        }

        //Método que comprueba si una relación está en el Histórico de la Empresa
        public static bool EstaHistoricoInstanciaTipActAmenCrit(InstanciaTiposActivosAmenazasCriteriosRiesgo instancia, int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<InstanciaTiposActivosAmenazasCriteriosRiesgo> LRelacion = (from i in agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer
                                                                            where i.IdTipoActivo == instancia.IdTipoActivo &&
                                                                            i.IdAmenaza == instancia.IdAmenaza &&
                                                                            i.IdCriterioRiesgo == instancia.IdCriterioRiesgo
                                                                            && i.IdEmpresa == IdEmpresa
                                                                            select i).ToList();
            //Si no se recoge nada es que la relación no estuvo anteriormente seleccionada por la empresa (Histórico)
            if (LRelacion.Count == 0)
            {
                return false;
            }
            //Si no, es porque la empresa tuvo seleccionada esa relación anteriormente (Actual=false)
            else
            {
                return true;
            }
        }
        //Método que recoge el número de Relaciones Tipo Activo - Amenaza - Criterio de riesgo actuales de una Empresa
        public static int NumRelacTipAmenCritEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int nRelac = (from InstTipAmenCrit in agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer
                          where InstTipAmenCrit.IdEmpresa == IdEmpresa && InstTipAmenCrit.Actual == true
                          select InstTipAmenCrit).Count();
            return nRelac;
        }

        //Método que recoge el número de Relaciones Tipo Activo - Amenaza - Criterio de riesgo de un Informe
        public static int NumRelacTipAmenCritEmpresaInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int nRelac = (from InstTipAmenCritInf in agenteBD.InstanciaTipactAmenCritriesgInformeEstablecer
                          where InstTipAmenCritInf.IdInforme == IdInforme
                          select InstTipAmenCritInf).Count();
            return nRelac;
        }

        //Método que recoge la Lista de Nombres de Relaciones Tipo Activo-Amenaza-Criterio de riesgo actuales de una Empresa
        public static List<String> ListaTiposActivosAmenEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<String> LTipActivAmenEmp = new List<String>();
            IQueryable<String> TiposActEmpr = (from InstTipAmenCrit in agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer
                                               join TipActiv in agenteBD.TiposActivosEstablecer
                                                    on InstTipAmenCrit.IdTipoActivo equals TipActiv.IdTipoActivo
                                               where InstTipAmenCrit.IdEmpresa == IdEmpresa && InstTipAmenCrit.Actual == true
                                               orderby InstTipAmenCrit.IdTipoActivo
                                               select TipActiv.TipoActivo).Distinct();
            foreach (String TipoActivoEmpresa in TiposActEmpr)
            {
                LTipActivAmenEmp.Add(TipoActivoEmpresa);
            }
            return LTipActivAmenEmp;
        }

        //Método que saca el número de relaciones Tipo Activo-Amenaza actuales ordenadas por Tipo Activo
        public static List<int> ListaNumTipActivAmenEmpr(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<int> LNumTipActivAmenEmp = new List<int>();
            //Sacamos todos los Id's de los de las relaciones 
            //Tipo Activo-Amenaza seleccionados por la Empresa
            IQueryable<int> NumIdsTiposActEmpr = (from InstTipAmenCrit in agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer
                                                  where InstTipAmenCrit.IdEmpresa == IdEmpresa && InstTipAmenCrit.Actual == true
                                                  orderby InstTipAmenCrit.IdTipoActivo
                                                  select InstTipAmenCrit.IdTipoActivo).Distinct();
            //De todos los Id's de Tipo de Activo de la Empresa, contamos cuantas relaciones
            //TipoActivo-Amenaza eligio la empresa con ese Tipo Activo
            foreach (int IdTipActEmp in NumIdsTiposActEmpr)
            {
                int NumTipActEmp = (from InstTipAmenCrit in agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer
                                    where InstTipAmenCrit.IdEmpresa == IdEmpresa &&
                                          InstTipAmenCrit.IdTipoActivo == IdTipActEmp && InstTipAmenCrit.Actual == true
                                    orderby InstTipAmenCrit.IdTipoActivo
                                    select InstTipAmenCrit.IdTipoActivo).Count();
                LNumTipActivAmenEmp.Add(NumTipActEmp);
            }
            return LNumTipActivAmenEmp;
        }

        //Recoge el número de relaciones Tipo Activo-Amenazas-Criterio Riesgo actuales que tiene la empresa con un IdTipoActivo dado
        public static int NumRelacionesTipoActAmenPorTipoActivo(int IdEmpresa, int IdTipoActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NumRelaciones = (from Rel in agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer
                                 where Rel.IdEmpresa == IdEmpresa && Rel.IdTipoActivo == IdTipoActivo && Rel.Actual == true
                                 select Rel).Count();
            return NumRelaciones;

        }


        //Método que hace un borrado lógico de todas las relaciones dependientes de una lista de relaciones Tipo Activo - Amenaza - Criterio Riesgo
        public static List<InstanciaTiposActivosAmenazasCriteriosRiesgo> EliminaInstanciasPorRelacTipActAmenCrit(List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelaciones)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Por cada amenaza de la lista
            //Lista de aquellas relaciones a las que se le hacen un borrado lógico
            List<InstanciaTiposActivosAmenazasCriteriosRiesgo> LRelacionesEliminadas = new List<InstanciaTiposActivosAmenazasCriteriosRiesgo>();
            foreach (Matriz_TipoActivosAmenazasCriteriosRiesgo Rel in LRelaciones)
            {
                //Recogemos las Instancias actuales 
                IQueryable<InstanciaTiposActivosAmenazasCriteriosRiesgo> InstTipActAmenCrit = from Instanc in agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer
                                                                                              where Instanc.IdTipoActivo == Rel.IdTipoActivo && Instanc.IdAmenaza == Rel.IdAmenaza &&
                                                                                               Instanc.IdCriterioRiesgo == Rel.IdCriterioRiesgo && Instanc.Actual == true
                                                                                              select Instanc;
                if (InstTipActAmenCrit.Count() != 0)
                {
                    //Para cada uno actualizamos el Valor Actual a false
                    foreach (InstanciaTiposActivosAmenazasCriteriosRiesgo Instancia in InstTipActAmenCrit)
                    {
                        Instancia.Actual = false;
                        //Añadimos a la lista de Relaciones Eliminadas
                        LRelacionesEliminadas.Add(Instancia);
                    }
                }
            }
            agenteBD.SaveChanges();
            return LRelacionesEliminadas;
        }

        //Método que restaura las instancias de una lista de relaciones tipo activo - amenaza - criterio de riesgo
        internal static List<InstanciaTiposActivosAmenazasCriteriosRiesgo> RestauraInstanciasPorRelacTipActAmenCrit(List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelaciones)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Por cada amenaza de la lista
            //Lista de aquellas relaciones a las que se le hacen un borrado lógico
            List<InstanciaTiposActivosAmenazasCriteriosRiesgo> LRelacionesRestauradas = new List<InstanciaTiposActivosAmenazasCriteriosRiesgo>();
            foreach (Matriz_TipoActivosAmenazasCriteriosRiesgo Rel in LRelaciones)
            {
                //Recogemos las Instancias actuales 
                IQueryable<InstanciaTiposActivosAmenazasCriteriosRiesgo> InstTipActAmenCrit = from Instanc in agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer
                                                                                              where Instanc.IdTipoActivo == Rel.IdTipoActivo && Instanc.IdAmenaza == Rel.IdAmenaza &&
                                                                                               Instanc.IdCriterioRiesgo == Rel.IdCriterioRiesgo
                                                                                              select Instanc;
                if (InstTipActAmenCrit.Count() != 0)
                {
                    //Para cada uno actualizamos el Valor Actual a true
                    foreach (InstanciaTiposActivosAmenazasCriteriosRiesgo Instancia in InstTipActAmenCrit)
                    {
                        Instancia.Actual = true;
                        //Añadimos a la lista de Relaciones Restauradas
                        LRelacionesRestauradas.Add(Instancia);
                    }
                }
            }
            agenteBD.SaveChanges();
            return LRelacionesRestauradas;
        }

        //Número total de instancias actuales de relaciones tipo activo - amenaza - criterio de riesgo
        internal static int NumeroTotalRelaciones(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NumRelaciones = (from Rel in agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer
                                 where Rel.IdEmpresa == IdEmpresa && Rel.Actual == true
                                 select Rel).Count();
            return NumRelaciones;
        }

        //Método que elimina de forma física todas las instancias Tipo Activo - Amenaza - Criterio asociadas a una empresa
        internal static void EliminaTotalInstanciasTipAmenCrit(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<InstanciaTiposActivosAmenazasCriteriosRiesgo> InstanciasEliminarQuery = from Instancia in agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer
                                                                                               where Instancia.IdEmpresa == IdEmpresa
                                                                                               select Instancia;
            if (InstanciasEliminarQuery.Count() != 0)
            {
                foreach (InstanciaTiposActivosAmenazasCriteriosRiesgo Inst in InstanciasEliminarQuery)
                {
                    agenteBD.InstanciaTiposActivosAmenazasCriteriosRiesgoEstablecer.DeleteObject(Inst);
                }
                agenteBD.SaveChanges();
            }
        }


    }
}
